home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / FREENET / MELL / NETLIB00 / NetLib / c / proto < prev    next >
Text File  |  1995-01-12  |  4KB  |  209 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #include "netdb.h"
  6. #include "netinet/in.h"
  7. #include "sys/socket.h"
  8.  
  9. #include "socketlib.h"
  10.  
  11. /*
  12.  * File handle for the protocols file
  13.  */
  14. static FILE *protofile = NULL;
  15.  
  16. /*
  17.  * Keep the file open between calls to these routines?
  18.  */
  19. static int keepopen = 0;
  20.  
  21. /*
  22.  * Local routines
  23.  */
  24. static int __setprotoent(int allowrewind);
  25. static struct protoent *__getprotoent(void);
  26.  
  27. /*
  28.  * Open and rewind the protocols file
  29.  */
  30. int setprotoent(int stayopen)
  31. {
  32.   /* Record whether the file should be kept open */
  33.   keepopen = stayopen;
  34.  
  35.   return __setprotoent(1);
  36. }
  37.  
  38. /*
  39.  * Do the real work of opening/rewinding the protocols file
  40.  */
  41. static int __setprotoent(int allowrewind)
  42. {
  43.   /* Open or rewind the file as necessary */
  44.   if (protofile) {
  45.     if (allowrewind)
  46.       rewind(protofile);
  47.   } else {
  48.     protofile = fopen("InetDBase:Protocols", "r");
  49.   }
  50.  
  51.   return (protofile == NULL) ? -1 : 0;
  52. }
  53.  
  54. /*
  55.  * Fetch the next entry from the protocols file
  56.  */
  57. struct protoent *getprotoent()
  58. {
  59.   struct protoent *proto;
  60.  
  61.   /* Open the file if necessary */
  62.   if (protofile == NULL)
  63.     if (__setprotoent(0) == -1)
  64.       return NULL;
  65.  
  66.   /* Do the actual read */
  67.   proto = __getprotoent();
  68.  
  69.   /* Close the file unless the user has prohibited it */
  70.   if (!keepopen)
  71.     endprotoent();
  72.  
  73.   return proto;
  74. }
  75.  
  76. /*
  77.  * Do the real work of getting an entry from the file
  78.  */
  79. struct protoent *__getprotoent()
  80. {
  81.   static struct protoent proto = {
  82.     NULL, NULL, 0
  83.   };
  84.  
  85.   char **item;
  86.   char *line;
  87.   char *element;
  88.   int  aliases;
  89.  
  90.   /* Free up any memory in use */
  91.   if (proto.p_name) {
  92.     for (item = proto.p_aliases; *item; item++)
  93.       free(*item);
  94.     free(proto.p_name);
  95.     free(proto.p_aliases);
  96.  
  97.     proto.p_name = NULL;
  98.   }
  99.  
  100.   /* Read a line from the file */
  101.   if ((line = __socketlib_readline(protofile)) == NULL)
  102.     return NULL;
  103.  
  104.   /* Extract the offical protocol name from the line */
  105.   element = strtok(line, " \t");
  106.   proto.p_name = strdup(element);
  107.  
  108.   /* Extract the port number from the line */
  109.   element = strtok(NULL, " \t");
  110.   proto.p_proto = atoi(element);
  111.  
  112.   /* Initialise the alias list */
  113.   proto.p_aliases = malloc(sizeof(char *));
  114.   proto.p_aliases[0] = NULL;
  115.   aliases = 1;
  116.  
  117.   /* Extract the aliases */
  118.   while ((element = strtok(NULL, " \t")) != NULL)
  119.   {
  120.      aliases += 1;
  121.      proto.p_aliases = realloc(proto.p_aliases, aliases * sizeof(char *));
  122.      proto.p_aliases[aliases-2] = strdup(element);
  123.      proto.p_aliases[aliases-1] = NULL;
  124.   }
  125.  
  126.   return &proto;
  127. }
  128.  
  129. /*
  130.  * Close the protocols file
  131.  */
  132. int endprotoent()
  133. {
  134.   int status = 0;
  135.  
  136.   /* If its open, close it */
  137.   if (protofile) {
  138.     status = fclose(protofile);
  139.     protofile = 0;
  140.   }
  141.  
  142.   return status;
  143. }
  144.  
  145. /*
  146.  * Search the protocols file for a given protocol name
  147.  */
  148. struct protoent *getprotobyname(const char *name)
  149. {
  150.   struct protoent *proto;
  151.   char            **alias;
  152.  
  153.   /* Open/rewind the file */
  154.   if (__setprotoent(1) == -1)
  155.     return NULL;
  156.  
  157.   /* Look through the file for a match */
  158.   while ((proto = __getprotoent()) != NULL) {
  159.  
  160.     /* Does the offical name match? */
  161.     if (strcmp(proto->p_name, name) == 0)
  162.       break;
  163.  
  164.     /* Do any of the aliases match? */
  165.     for (alias = proto->p_aliases; *alias; alias++)
  166.     {
  167.       if (strcmp(*alias, name) == 0)
  168.         break;
  169.     }
  170.  
  171.     /* Did any of the aliases match? */
  172.     if (*alias)
  173.       break;
  174.   }
  175.  
  176.   /* Close the file unless the user has prohibited it */
  177.   if (!keepopen)
  178.     endprotoent();
  179.  
  180.   return proto;
  181. }
  182.  
  183. /*
  184.  * Search the protocols file for a given number
  185.  */
  186. struct protoent *getprotobynumber(int protonum)
  187. {
  188.   struct protoent *proto;
  189.  
  190.   /* Open/rewind the file */
  191.   if (__setprotoent(1) == -1)
  192.     return NULL;
  193.  
  194.   /* Look through the file for a match */
  195.   while ((proto = __getprotoent()) != NULL) {
  196.  
  197.     /* If the protocol number matches, we've found it */
  198.     if (proto->p_proto == protonum)
  199.       break;
  200.  
  201.   }
  202.  
  203.   /* Close the file unless the user has prohibited it */
  204.   if (!keepopen)
  205.     endprotoent();
  206.  
  207.   return proto;
  208. }
  209.